#include "Col.ph"
#ifdef __GNUG__
#pragma implementation
#endif

#include "Timer.h"
#include "Class.h"
#include "System.h"
#include "ET_time.h"

//---- Timer -------------------------------------------------------------------

NewMetaImpl(Timer,SysEvtHandler, (TB(syncmode), T(timeout), TP(next),
							T(time), T(abstime)));

Timer::Timer(long ms, bool s) : syncmode(s), time(ms), SysEvtHandler(0)
{
	next= 0;
	Install();
}

Timer::~Timer()
{
	UnInstall();
}

bool Timer::Notify()
{
	return FALSE;
}

void Timer::Reset()
{
	UnInstall();
	Install();
}

void Timer::Install()
{
	if (next) {
		fprintf(stderr, "Timer::Install: next != 0\n");
		UnInstall();
	}

	timeout= FALSE;

	abstime= gSystem->Now() + time;

	gSystem->AddTimer(this);
}

bool Timer::UnInstall()
{
	bool rc= gSystem->RemoveTimer(this);
	next= 0;
	return rc;
}

bool Timer::CheckTimer(Timer **head, const Time &now)
{
	if (abstime <= now) {
		if (head)
			*head= next;
		next= 0;
		timeout= TRUE;
		Notify();
		return TRUE;
	}
	return FALSE;
}

//---- timeout handler for updating clocks & dates -----------------------------

class TOHandler : public Timer {
private:
	ObjTime *tt;
public:
	TOHandler(ObjTime *t, long ms) : Timer(ms, eSync)
		{ tt= t; }
	bool Notify();
};

bool TOHandler::Notify()
{
	if (tt)
		tt->Update();
	Reset();
	return TRUE;
}

//---- ObjTime -----------------------------------------------------------------

ObjTime gTime;

NewMetaImpl(ObjTime,Object, (TP(updatehandler)));

ObjTime::ObjTime()
{
	updatehandler= 0;
	l= 0;
}

ObjTime::~ObjTime()
{
	if (updatehandler) {
		updatehandler->Remove();
		updatehandler= 0;
	}
	l= 0;
}

void ObjTime::Init()
{
	time((time_t*)&now);
	l= localtime((time_t*)&now);

	updatehandler= new TOHandler(this, 1000);
}

void ObjTime::Update()
{
	int osec= l->tm_sec;

	time((time_t*)&now);
	l= localtime((time_t*)&now);

	if (osec != l->tm_sec)
		Changed();
}

void ObjTime::GetHMS(int *h, int *m, int *s)
{
	if (updatehandler == 0)
		Init();

	*h= l->tm_hour;
	*m= l->tm_min;
	*s= l->tm_sec;
}

char *ObjTime::Format(const char *fmt, char *buf, int len)
{
	if (updatehandler == 0)
		Init();
	if (buf == 0) {
		static char bbuf[1000];
		strftime(bbuf, sizeof bbuf, fmt, l);
		return bbuf;
	} else {
		strftime(buf, len, fmt, l);
		return buf;
	}
}

